package org.example;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

public class ShoppingCart {

    private Map<Fruit, Integer> items = new HashMap<>();

    /**
     * 是否启用满减活动
     */
    private boolean isOffSpendHundred;

    /**
     * 满100减多少，商场优惠设置，默认满100减10，可设置
     */
    private BigDecimal offRmbSpendHundred;
    
    private BigDecimal DEFAULT_OFF_RMB_SPEND_HUNDRED = new BigDecimal("10");

    /**
     * 默认没有满减活动
     */
    public ShoppingCart() {
        this.isOffSpendHundred = false;
        this.offRmbSpendHundred = new BigDecimal(0);
    }

    public ShoppingCart(boolean isOffSpendHundred) {
        this.isOffSpendHundred = isOffSpendHundred;
        if (isOffSpendHundred) {
            this.offRmbSpendHundred = DEFAULT_OFF_RMB_SPEND_HUNDRED;
        }
    }

    public ShoppingCart(boolean isOffSpendHundred, BigDecimal offRmbSpendHundred) {
        this.isOffSpendHundred = isOffSpendHundred;
        this.offRmbSpendHundred = offRmbSpendHundred;
    }

    public void addItem(Fruit fruit, int quantity) {
        if (quantity < 0) {
            throw new IllegalArgumentException("购买数量不能为负数");
        }
        items.put(fruit, items.getOrDefault(fruit, 0) + quantity);
    }

    public BigDecimal calculateTotalPrice() {
        BigDecimal totalPrice = items.entrySet().stream()
                .map(entry -> entry.getKey().calculatePrice(entry.getValue(), entry.getKey().getDiscount()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // 是否启用满减活动
        if (isOffSpendHundred) {
            // 默认活动：每满100减10
            totalPrice = ShoppingCartUtil.discountEveryHundred(totalPrice, offRmbSpendHundred);
        }
        return totalPrice;
    }

    public boolean verifyTotalPrice() {
        BigDecimal manualTotal = BigDecimal.ZERO;
        for (Map.Entry<Fruit, Integer> entry : items.entrySet()) {
            manualTotal = manualTotal.add(entry.getKey().calculatePrice(entry.getValue(), entry.getKey().getDiscount()));
        }
        BigDecimal calculatedTotal = calculateTotalPrice();
        return calculatedTotal.subtract(manualTotal).abs().compareTo(new BigDecimal("0.0001")) < 0;
    }

    public Map<Fruit, Integer> getItems() {
        return items;
    }

    public boolean isOffSpendHundred() {
        return isOffSpendHundred;
    }

    public void setOffSpendHundred(boolean offSpendHundred) {
        isOffSpendHundred = offSpendHundred;
    }

}
